#include "gtktreednd.h"
#include "gtktreeprivate.h"
#include "gtkcellrenderer.h"
+#include "gtkextendedlayout.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkbuildable.h"
GObject *child,
const gchar *type);
static void gtk_tree_view_buildable_init (GtkBuildableIface *iface);
-
+static void gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface);
static gboolean scroll_row_timeout (gpointer data);
static void add_scroll_timeout (GtkTreeView *tree_view);
G_DEFINE_TYPE_WITH_CODE (GtkTreeView, gtk_tree_view, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gtk_tree_view_buildable_init))
+ gtk_tree_view_buildable_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+ gtk_tree_view_extended_layout_init))
+
static void
gtk_tree_view_class_init (GtkTreeViewClass *class)
return real_requested_width;
}
+static gint
+gtk_tree_view_get_real_natural_width_from_column (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column)
+{
+ GtkTreeViewColumnPrivate *column_priv;
+ GtkRequisition button_natural_size;
+ gint column_natural_width;
+
+ column_priv = GTK_TREE_VIEW_COLUMN_GET_PRIVATE (column);
+ column_natural_width = column_priv->natural_width;
+
+ if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE))
+ {
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (column->button),
+ NULL, &button_natural_size);
+
+ column_natural_width = MAX (column_natural_width, button_natural_size.width);
+ }
+
+ return column_natural_width;
+}
+
/* GtkWidget::size_allocate helper */
static void
gtk_tree_view_size_allocate_columns (GtkWidget *widget,
GList *list, *first_column, *last_column;
GtkTreeViewColumn *column;
GtkAllocation allocation;
- gint width = 0;
+ gint width = 0, natural_width;
gint extra, extra_per_column, extra_for_last;
gint full_requested_width = 0;
+ gint full_natural_width = 0;
gint number_of_expand_columns = 0;
gboolean column_changed = FALSE;
gboolean rtl;
continue;
full_requested_width += gtk_tree_view_get_real_requested_width_from_column (tree_view, column);
+ full_natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column);
if (column->expand)
number_of_expand_columns++;
}
else
{
+ full_natural_width -= full_requested_width;
extra = MAX (widget->allocation.width - full_requested_width, 0);
+ natural_width = MIN (extra, full_natural_width);
extra_for_last = 0;
tree_view->priv->last_extra_space = extra;
list = (rtl ? list->prev : list->next))
{
gint real_requested_width = 0;
+ gint real_natural_width = 0;
gint old_width;
column = list->data;
}
real_requested_width = gtk_tree_view_get_real_requested_width_from_column (tree_view, column);
+ real_natural_width = gtk_tree_view_get_real_natural_width_from_column (tree_view, column);
+ real_natural_width -= real_requested_width;
allocation.x = width;
column->width = real_requested_width;
+ if (full_natural_width > 0)
+ column->width += natural_width * real_natural_width / full_natural_width;
if (column->expand)
{
if (number_of_expand_columns == 1)
for (list = tree_view->priv->columns; list; list = list->next)
{
- gint tmp_width;
- gint tmp_height;
+ GtkTreeViewColumnPrivate *column_priv;
+ GtkRequisition requested_size;
+ GtkRequisition natural_size;
+ gint padding;
column = list->data;
+ column_priv = GTK_TREE_VIEW_COLUMN_GET_PRIVATE (column);
if (! column->visible)
continue;
node->children?TRUE:FALSE);
gtk_tree_view_column_cell_get_size (column,
NULL, NULL, NULL,
- &tmp_width, &tmp_height);
+ &requested_size.width,
+ &requested_size.height);
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (column),
+ NULL, &natural_size);
if (!is_separator)
{
- tmp_height += vertical_separator;
- height = MAX (height, tmp_height);
+ requested_size.height += vertical_separator;
+ height = MAX (height, requested_size.height);
height = MAX (height, tree_view->priv->expander_size);
}
else
if (gtk_tree_view_is_expander_column (tree_view, column))
{
- tmp_width = tmp_width + horizontal_separator + (depth - 1) * tree_view->priv->level_indentation;
+ padding = horizontal_separator + (depth - 1) * tree_view->priv->level_indentation;
if (TREE_VIEW_DRAW_EXPANDERS (tree_view))
- tmp_width += depth * tree_view->priv->expander_size;
+ padding += depth * tree_view->priv->expander_size;
}
else
- tmp_width = tmp_width + horizontal_separator;
+ padding = horizontal_separator;
if (draw_vgrid_lines)
{
if (list->data == first_column || list->data == last_column)
- tmp_width += grid_line_width / 2.0;
+ padding += grid_line_width / 2.0;
else
- tmp_width += grid_line_width;
+ padding += grid_line_width;
}
- if (tmp_width > column->requested_width)
+ requested_size.width += padding;
+ natural_size.width += padding;
+
+ if (requested_size.width > column->requested_width ||
+ natural_size.width > column_priv->natural_width)
{
retval = TRUE;
- column->requested_width = tmp_width;
+ column->requested_width = requested_size.width;
+ column_priv->natural_width = natural_size.width;
}
}
return tree_view->priv->tooltip_column;
}
+static void
+gtk_tree_view_extended_layout_get_desired_size (GtkExtendedLayout *layout,
+ GtkRequisition *minimal_size,
+ GtkRequisition *desired_size)
+{
+ GtkTreeView *tree_view;
+ gint natural_width = 0;
+ GList *column_iter;
+ GtkRequisition requisition;
+
+ tree_view = GTK_TREE_VIEW (layout);
+
+ gtk_widget_size_request (GTK_WIDGET (layout), &requisition);
+
+ for (column_iter = tree_view->priv->columns; column_iter; column_iter = column_iter->next)
+ {
+ GtkTreeViewColumn *column = column_iter->data;
+
+ if (!column->visible)
+ continue;
+
+ natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column);
+ }
+
+ if (minimal_size)
+ *minimal_size = requisition;
+
+ if (desired_size)
+ {
+ desired_size->height = requisition.height;
+ desired_size->width = natural_width;
+ }
+}
+
+static void
+gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+ iface->get_desired_size = gtk_tree_view_extended_layout_get_desired_size;
+}
+
+
#define __GTK_TREE_VIEW_C__
#include "gtkaliasdef.c"
#include "gtkbutton.h"
#include "gtkalignment.h"
#include "gtklabel.h"
+#include "gtkextendedlayout.h"
#include "gtkhbox.h"
#include "gtkmarshalers.h"
#include "gtkarrow.h"
/* GtkBuildable implementation */
static void gtk_tree_view_column_buildable_init (GtkBuildableIface *iface);
+static void gtk_tree_view_column_extended_layout_init (GtkExtendedLayoutIface *iface);
+
static guint tree_column_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_CODE (GtkTreeViewColumn, gtk_tree_view_column, GTK_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
gtk_tree_view_column_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gtk_tree_view_column_buildable_init))
+ gtk_tree_view_column_buildable_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+ gtk_tree_view_column_extended_layout_init))
+
static void
G_MAXINT,
-1,
GTK_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (GtkTreeViewColumnPrivate));
}
static void
* primarily by the #GtkTreeView.
**/
void
-gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
+gtk_tree_view_column_cell_get_real_size (GtkTreeViewColumn *tree_column,
const GdkRectangle *cell_area,
gint *x_offset,
gint *y_offset,
- gint *width,
- gint *height)
+ GtkRequisition *minimal_size,
+ GtkRequisition *desired_size)
{
GList *list;
gboolean first_cell = TRUE;
g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
- if (height)
- * height = 0;
- if (width)
- * width = 0;
+ minimal_size->height = 0;
+ minimal_size->width = 0;
+ desired_size->height = 0;
+ desired_size->width = 0;
gtk_widget_style_get (tree_column->tree_view, "focus-line-width", &focus_line_width, NULL);
{
GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
gboolean visible;
- gint new_height = 0;
- gint new_width = 0;
+ GtkRequisition min_req, nat_req;
+
g_object_get (info->cell, "visible", &visible, NULL);
if (visible == FALSE)
continue;
- if (first_cell == FALSE && width)
- *width += tree_column->spacing;
+ if (first_cell == FALSE)
+ {
+ min_req.width += tree_column->spacing;
+ nat_req.width += tree_column->spacing;
+ }
+
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (info->cell),
+ &min_req, &nat_req);
- gtk_cell_renderer_get_size (info->cell,
- tree_column->tree_view,
- cell_area,
- x_offset,
- y_offset,
- &new_width,
- &new_height);
+ min_req.width += focus_line_width * 2;
+ min_req.height += focus_line_width * 2;
+ nat_req.width += focus_line_width * 2;
+ nat_req.height += focus_line_width * 2;
+
+ info->requested_width = MAX (info->requested_width, min_req.width);
- if (height)
- * height = MAX (*height, new_height + focus_line_width * 2);
- info->requested_width = MAX (info->requested_width, new_width + focus_line_width * 2);
- if (width)
- * width += info->requested_width;
first_cell = FALSE;
+
+ if (minimal_size)
+ *minimal_size = min_req;
+
+ if (desired_size)
+ *desired_size = nat_req;
}
}
+void
+gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
+ const GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ GtkRequisition min_req;
+
+ gtk_tree_view_column_cell_get_real_size (tree_column, cell_area,
+ x_offset, y_offset, &min_req, NULL);
+
+ if (width)
+ *width = min_req.width;
+
+ if (height)
+ *height = min_req.height;
+}
+
/* rendering, event handling and rendering focus are somewhat complicated, and
* quite a bit of code. Rather than duplicate them, we put them together to
* keep the code in one place.
return tree_column->tree_view;
}
+static void
+gtk_tree_view_column_extended_layout_get_desired_size (GtkExtendedLayout *layout,
+ GtkRequisition *minimal_size,
+ GtkRequisition *desired_size)
+{
+ gtk_tree_view_column_cell_get_real_size (GTK_TREE_VIEW_COLUMN (layout),
+ NULL, NULL, NULL,
+ minimal_size, desired_size);
+}
+
+static void
+gtk_tree_view_column_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+ iface->get_desired_size = gtk_tree_view_column_extended_layout_get_desired_size;
+}
+
+
#define __GTK_TREE_VIEW_COLUMN_C__
#include "gtkaliasdef.c"